/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jschoolmanagerportable.gui.model;

import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.swing.table.AbstractTableModel;
import jschoolmanagerportable.model.Alumno;
import jschoolmanagerportable.model.Asignatura;
import jschoolmanagerportable.model.Nota;

/**
 *
 * @author Administrador
 */
public class NotasAdminModelTable extends AbstractTableModel {

    private String[] columnNames;
    private Object[][] data;
    private int cantAlumnos;
    private int cantColumnas;
    private Collection<Alumno> alumnos;
    private Asignatura asignatura;
    private EntityManager entityManager;
    private int periodo;

    public NotasAdminModelTable(Collection<Alumno> alumnos, Asignatura asignatura, EntityManager entityManager, int periodo) {
        cantAlumnos = alumnos.size();
        cantColumnas = asignatura.getCantidaddenotas() + 2; //Nombre + promedio
        this.alumnos = alumnos;
        this.asignatura = asignatura;
        this.entityManager = entityManager;
        this.periodo=periodo;

        columnNames = new String[cantColumnas];
        for (int x = 0; x < cantColumnas; x++) {
            if (x == 0) {
                columnNames[x] = "Nombres";
            } else if (x == (cantColumnas - 1)) {
                columnNames[x] = "Prom";
            } else {
                columnNames[x] = "N" + x;
            }
        }
        //*******************************************


        data = new Object[cantAlumnos][cantColumnas];
        int x = 0;
        for (Alumno alumno : alumnos) {
            data[x][0] = alumno.getApellidos() + " " + alumno.getNombres();
            Object[] notas = buscaNotasAlumno(alumno, cantColumnas - 2, periodo);
            for (int y = 1; y < (cantColumnas - 1); y++) {
                data[x][y] = notas[y - 1];
            }
            actualizaPromedio(x);
            x++;
        }
    }

    public int getRowCount() {
        return data.length;
    }

    public int getColumnCount() {
        return columnNames.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return data[rowIndex][columnIndex];
    }

    //******************************************************************
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col == 0 || col == (this.getColumnCount() - 1)) {
            return false;
        } else {
            return true;
        }
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        persisteNota(row, col, (Double) value);
        fireTableCellUpdated(row, col);
    }

    //*********************************
    public void actualizaPromedio(int row) {
        double suma = 0;
        int cantNotas = 0;
        for (int x = 1; x <= (data[row].length - 2); x++) {
            double dblPaso = (Double) data[row][x];
            suma += dblPaso;
            if (dblPaso > 0.0) {
                cantNotas++;
            }
        }
        double prom = suma / (cantNotas);
        data[row][cantColumnas - 1] = roundDouble(prom, 1);
        fireTableCellUpdated(row, (cantColumnas - 1));
    }

    public double roundDouble(double d, int places) {
        return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10,
                (double) places);
    }

    private void persisteNota(int row, int col, double notaDbl) {
        Alumno alumno = (Alumno) alumnos.toArray()[row];
        int nnota = col;
        Query notasQuery = entityManager.createNamedQuery("Nota.findByAsignaturaAlumnoPeriodoNNota");
        notasQuery.setParameter("asignatura", asignatura);
        notasQuery.setParameter("alumno", alumno);
        notasQuery.setParameter("nnota", nnota);
        notasQuery.setParameter("periodo", periodo);
        Nota nota;
        try {
            nota = (Nota) notasQuery.getSingleResult();
            nota.setNota(notaDbl);
        } catch (javax.persistence.NoResultException e) {
            nota = new Nota();
            nota.setIdalumno(alumno);
            nota.setIdasignatura(asignatura);
            nota.setNnota(nnota);
            nota.setNota(notaDbl);
            nota.setPeriodo(periodo);
        }
        entityManager.getTransaction().begin();
        if (nota.getNota() == 0.0) {
            entityManager.remove(nota);
        } else {
            entityManager.persist(nota);
        }
        entityManager.getTransaction().commit();
    }

    public Object[] buscaNotasAlumno(Alumno alumno, int cantNotas, int periodo) {
        Object[] notas = new Object[cantNotas];
        Query notasQuery = entityManager.createNamedQuery("Nota.findByAsignaturaAlumnoPeriodo");
        notasQuery.setParameter("asignatura", asignatura);
        notasQuery.setParameter("alumno", alumno);
        notasQuery.setParameter("periodo", periodo);
        Object[] notasBD = notasQuery.getResultList().toArray();
        for (int x = 0; x < notasBD.length; x++) {
            Nota nota = (Nota) notasBD[x];
            notas[nota.getNnota() - 1] = nota.getNota();
        }

        Double dbl = 0.0;
        for (int x = 0; x < notas.length; x++) {
            if (notas[x] == null) {
                notas[x] = 0.0;
            }
        }
        return notas;
    }
}
